home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d931.lha
/
Modules
/
TimerDevice
/
TimerDevice.mod
/
TimerDevice.mod
Wrap
Text File
|
1993-12-20
|
10KB
|
414 lines
IMPLEMENTATION MODULE TimerDevice;
(* Die Anleitungen und Erläuterungen befinden sich im Definitionsfile *)
(* Compiler M2Amiga V4.097d © 1991 by Andre Wiethoff *)
(*$ StackChk:=FALSE *)
(*$ RangeChk:=FALSE *)
(*$ OverflowChk:=FALSE *)
(*$ NilChk:=FALSE *)
(*$ CaseChk:=FALSE *)
(*$ ReturnChk:=FALSE *)
(*$ Volatile:=FALSE *)
(*$ LargeVars:=FALSE *)
FROM SYSTEM IMPORT ADR,LONGSET,ASSEMBLE;
FROM ExecD IMPORT MsgPortPtr,TaskPtr,MsgPort,IOStdReq,DevicePtr;
FROM ExecL IMPORT OpenDevice,AddPort,FindTask,RemPort,CloseDevice,DoIO;
FROM Timer IMPORT timerName,TimeRequest,TimeVal,addRequest,getSysTime,
setSysTime;
CONST daysPerLeapYear = 366;
daysPerYear = 365;
daysPerWeek = 7;
hoursPerDay = 24;
minutesPerHour = 60;
secondsPerMinute = 60;
secondsPerHour = minutesPerHour*secondsPerMinute;
secondsPerDay = hoursPerDay*secondsPerHour;
secondsPerYear = daysPerYear*secondsPerDay;
secondsPerLeapYear = daysPerLeapYear*secondsPerDay;
TYPE ControlD = (hold,busy,irq,adj);
ControlDSet = SET OF ControlD;
ControlE = (mask,itrp,t0,t1);
ControlESet = SET OF ControlE;
ControlF = (reset,stop,t12,test);
ControlFSet = SET OF ControlF;
RealClock = RECORD
timeDate : ARRAY[0..12] OF LONGCARD;
pad1 : ARRAY[0..2] OF [0..255];
cd : ControlDSet;
pad2 : ARRAY[0..2] OF [0..255];
ce : ControlESet;
pad3 : ARRAY[0..2] OF [0..255];
cf : ControlFSet;
END;
VAR
task : TaskPtr;
msgPort : MsgPort;
timeReq : TimeRequest;
opened : BOOLEAN;
daysOfMonth : POINTER TO ARRAY[0..11] OF LONGCARD;
(*$ EntryExitCode:=FALSE *)
PROCEDURE Year;
BEGIN
ASSEMBLE(
DC.L 31,28,31,30,31,30,31,31,30,31,30,31
END);
END Year;
(*$ EntryExitCode:=FALSE *)
PROCEDURE LeapYear;
BEGIN
ASSEMBLE(
DC.L 31,29,31,30,31,30,31,31,30,31,30,31
END);
END LeapYear;
PROCEDURE OpenTimer(timer : CARDINAL) : DevicePtr;
BEGIN
IF opened THEN
CloseTimer;
END;
IF timer#0 THEN
timer:=1;
END;
task:=FindTask(0);
msgPort.sigTask:=task;
AddPort(ADR(msgPort));
OpenDevice(ADR(timerName),timer,ADR(timeReq),LONGSET{});
IF (timeReq.node.device#NIL) AND (timeReq.node.error=0) THEN
timeReq.node.message.replyPort:=ADR(msgPort);
opened:=TRUE;
ELSE
RemPort(ADR(msgPort));
END;
IF opened THEN
RETURN timeReq.node.device;
ELSE
RETURN NIL;
END;
END OpenTimer;
PROCEDURE WaitSecs(seconds,micros : LONGCARD);
BEGIN
IF opened THEN
timeReq.time.secs:=seconds;
timeReq.time.micro:=micros;
timeReq.node.command:=addRequest;
DoIO(ADR(timeReq));
END;
END WaitSecs;
PROCEDURE GetSystemTime(VAR timeVal : TimeVal);
BEGIN
IF opened THEN
timeReq.node.command:=getSysTime;
DoIO(ADR(timeReq));
timeVal:=timeReq.time;
END;
END GetSystemTime;
PROCEDURE SetSystemTime(timeVal : TimeVal);
BEGIN
IF opened THEN
timeReq.node.command:=setSysTime;
timeReq.time:=timeVal;
DoIO(ADR(timeReq));
END;
END SetSystemTime;
PROCEDURE MakeTimeList(timeVal : TimeVal;
VAR timeList : TimeList);
VAR n,t,q,qo:LONGCARD;
BEGIN
n:=(timeVal.secs DIV secondsPerDay);
t:=1978;
IF ((t MOD 4=0) AND (t MOD 100#0)) OR (t MOD 400=0) THEN
q:=daysPerLeapYear;
ELSE
q:=daysPerYear;
END;
WHILE n>=q DO
DEC(n,q); INC(t);
IF ((t MOD 4=0) AND (t MOD 100#0)) OR (t MOD 400=0) THEN
q:=daysPerLeapYear;
ELSE
q:=daysPerYear;
END;
END;
WITH timeList DO
year:=t; t:=0;
IF q=daysPerLeapYear THEN
daysOfMonth:=ADR(LeapYear);
ELSE
daysOfMonth:=ADR(Year);
END;
WHILE n>=daysOfMonth^[t] DO DEC(n,daysOfMonth^[t]); INC(t); END;
month:=t+1;
day:=n+1;
hour:=(timeVal.secs DIV secondsPerHour) MOD hoursPerDay;
minute:=(timeVal.secs DIV secondsPerMinute) MOD minutesPerHour;
second:=timeVal.secs MOD secondsPerMinute;
week:=(timeVal.secs DIV secondsPerDay) DIV daysPerWeek;
dayOfWeek:=(timeVal.secs DIV secondsPerDay) MOD daysPerWeek;
END;
END MakeTimeList;
PROCEDURE MakeTimeVal(timeList : TimeList;
VAR timeVal : TimeVal) : BOOLEAN;
VAR n,t : LONGCARD;
ok : BOOLEAN;
BEGIN
ok:=TRUE; n:=0;
IF timeList.second<secondsPerMinute THEN
INC(n,timeList.second);
ELSE
INC(n,(timeList.second MOD secondsPerMinute));
ok:=FALSE;
END;
IF timeList.minute<secondsPerMinute THEN
INC(n,timeList.minute*secondsPerMinute);
ELSE
INC(n,(timeList.minute MOD minutesPerHour)*secondsPerMinute);
ok:=FALSE;
END;
IF timeList.hour<hoursPerDay THEN
INC(n,timeList.hour*secondsPerHour);
ELSE
INC(n,(timeList.hour MOD hoursPerDay)*secondsPerHour);
ok:=FALSE;
END;
IF ((timeList.year MOD 4=0) AND (timeList.year MOD 100#0)) OR
(timeList.year MOD 400=0) THEN
daysOfMonth:=ADR(LeapYear);
ELSE
daysOfMonth:=ADR(Year);
END;
IF (timeList.month<13) AND (timeList.month>0) THEN
FOR t:=1 TO timeList.month-1 DO
INC(n,daysOfMonth^[t-1]*secondsPerDay);
END;
ELSE
ok:=FALSE;
END;
IF (timeList.month>0) AND (timeList.month<13) THEN
IF (timeList.day<=daysOfMonth^[timeList.month-1]) AND (timeList.day>0) THEN
INC(n,(timeList.day-1)*secondsPerDay);
ELSE
ok:=FALSE;
END;
END;
IF (timeList.year>1977) AND (timeList.year<2114) THEN
FOR t:=1978 TO timeList.year-1 DO
IF ((t MOD 4=0) AND (t MOD 100#0)) OR (t MOD 400=0) THEN
INC(n,secondsPerLeapYear);
ELSE
INC(n,secondsPerYear);
END;
END;
ELSE
ok:=FALSE;
END;
timeVal.secs:=n;
timeVal.micro:=0;
RETURN ok;
END MakeTimeVal;
PROCEDURE GetDaysOfMonth(year,month : LONGCARD) : LONGCARD;
BEGIN
IF (month>0) AND (month<13) AND (year>1600) AND (year<2114) THEN
IF month=2 THEN
IF ((year MOD 4=0) AND (year MOD 100#0)) OR (year MOD 400=0) THEN
daysOfMonth:=ADR(LeapYear);
ELSE
daysOfMonth:=ADR(Year);
END;
END;
RETURN daysOfMonth^[month-1];
ELSE
RETURN 0;
END;
END GetDaysOfMonth;
PROCEDURE CloseTimer;
BEGIN
IF opened THEN
RemPort(ADR(msgPort));
CloseDevice(ADR(timeReq));
opened:=FALSE;
END;
END CloseTimer;
VAR realClock : POINTER TO RealClock;
oldA2000[0D80000H] : INTEGER; (* Dummy-Variable *)
A500[0DC0000H] : INTEGER;
PROCEDURE BackupClockExistent() : BOOLEAN;
PROCEDURE TestActualClock() : BOOLEAN;
VAR fl1,fl2 : BOOLEAN;
BEGIN
EXCL(realClock^.cd,hold);
fl1:=(busy IN realClock^.cd);
INCL(realClock^.cd,hold);
fl2:=(busy IN realClock^.cd);
EXCL(realClock^.cd,hold);
RETURN (fl1#fl2);
END TestActualClock;
VAR return : BOOLEAN;
BEGIN
return:=TRUE;
realClock:=ADR(A500);
IF NOT TestActualClock() THEN
realClock:=ADR(oldA2000);
IF NOT TestActualClock() THEN
return:=FALSE;
END;
END;
RETURN return;
END BackupClockExistent;
PROCEDURE ResetBackupClock;
BEGIN
INCL(realClock^.cf,reset);
EXCL(realClock^.cf,reset);
END ResetBackupClock;
PROCEDURE StopBackupClock;
BEGIN
INCL(realClock^.cf,stop);
END StopBackupClock;
PROCEDURE StartBackupClock;
BEGIN
EXCL(realClock^.cf,stop);
END StartBackupClock;
PROCEDURE GetBackupClock(VAR timeList : TimeList);
VAR t,n : LONGCARD;
BEGIN
WITH realClock^ DO
INCL(cd,hold);
WHILE busy IN cd DO END;
timeList.second:=(timeDate[0] MOD 16)+(timeDate[1] MOD 8)*10;
timeList.minute:=(timeDate[2] MOD 16)+(timeDate[3] MOD 8)*10;
timeList.hour:=(timeDate[4] MOD 16)+(timeDate[5] MOD 4)*10;
timeList.day:=(timeDate[6] MOD 16)+(timeDate[7] MOD 4)*10;
timeList.month:=(timeDate[8] MOD 16)+(timeDate[9] MOD 2)*10;
timeList.year:=(timeDate[10] MOD 16)+(timeDate[11] MOD 16)*10;
INC(timeList.year,1900);
EXCL(cd,hold);
n:=0;
IF ((timeList.year MOD 4=0) AND (timeList.year MOD 100#0)) OR
(timeList.year MOD 400=0) THEN
daysOfMonth:=ADR(LeapYear);
ELSE
daysOfMonth:=ADR(Year);
END;
IF (timeList.month<13) AND (timeList.month>0) THEN
FOR t:=1 TO timeList.month-1 DO
INC(n,daysOfMonth^[t-1]*secondsPerDay);
END;
END;
IF (timeList.month>0) AND (timeList.month<13) THEN
IF (timeList.day<=daysOfMonth^[timeList.month-1]) AND (timeList.day>0)
THEN INC(n,(timeList.day-1)*secondsPerDay);
END;
END;
IF (timeList.year>1977) AND (timeList.year<2114) THEN
FOR t:=1978 TO timeList.year-1 DO
IF ((t MOD 4=0) AND (t MOD 100#0)) OR (t MOD 400=0) THEN
INC(n,secondsPerLeapYear);
ELSE
INC(n,secondsPerYear);
END;
END;
END;
timeList.week:=(n DIV secondsPerDay) DIV daysPerWeek;
timeList.dayOfWeek:=(n DIV secondsPerDay) MOD daysPerWeek;
END;
END GetBackupClock;
PROCEDURE SetBackupClock(timeList : TimeList);
PROCEDURE Set(value : LONGCARD;
VAR c1,c2 : LONGCARD);
BEGIN
c1:=((c1 DIV 16)*16)+(value MOD 10);
c2:=((c2 DIV 16)*16)+((value DIV 10) MOD 10);
END Set;
VAR lc : LONGCARD;
BEGIN
WITH realClock^ DO
INCL(cd,hold);
WHILE busy IN cd DO END;
Set(timeList.second,timeDate[0],timeDate[1]);
Set(timeList.minute,timeDate[2],timeDate[3]);
Set(timeList.hour,timeDate[4],timeDate[5]);
Set(timeList.day,timeDate[6],timeDate[7]);
Set(timeList.month,timeDate[8],timeDate[9]);
Set(timeList.year-1900,timeDate[10],timeDate[11]);
EXCL(cd,hold);
END;
END SetBackupClock;
BEGIN
opened:=FALSE;
realClock:=ADR(A500);
CLOSE
CloseTimer;
END TimerDevice.